package com.gitee.target123.develop.common.util;

import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.UnsupportedTemporalTypeException;

/**
 * java8 日期转换工具
 */
public class Java8DateFormatUtil {

    private static final DateTimeFormatter dateTimeFormatter;
    private static final String dateTimePattern = "yyyy-MM-dd HH:mm:ss";
    //中国时区+8
    public static final ZoneOffset CHINA = ZoneOffset.ofHours(8);

    static {
        dateTimeFormatter = DateTimeFormatter.ofPattern(dateTimePattern);
    }

    public static DateTimeFormatter getDateTimeFormatter() {
        return dateTimeFormatter;
    }

    /**
     * 默认yyyy-MM-dd
     */
    public static String format(LocalDate date){
        return date.toString();
    }
    /**
     * 默认yyyy-MM-dd HH:mm:ss
     */
    public static String format(LocalDateTime dateTime){
        return dateTime.format(getDateTimeFormatter());
    }
    /**
     * 默认yyyy-MM-dd HH:mm:ss
     */
    public static String format(Instant instant){
        return format(toLocalDateTime(instant));
    }

    /**
     * @param date 默认yyyy-MM-dd
     */
    public static LocalDate toLocalDate(String date){
        return LocalDate.parse(date);
    }
    public static LocalDate toLocalDate(LocalDateTime dateTime){
        return dateTime.toLocalDate();
    }
    public static LocalDate toLocalDate(Instant instant){
        return toLocalDate(toLocalDateTime(instant));
    }

    /**
     * @param dateTime 默认yyyy-MM-dd HH:mm:ss
     */
    public static LocalDateTime toLocalDateTime(String dateTime){
        return LocalDateTime.parse(dateTime,getDateTimeFormatter());
    }
    public static LocalDateTime toLocalDateTime(LocalDate date){
        return date.atStartOfDay();
    }
    public static LocalDateTime toLocalDateTime(Instant instant){
        return LocalDateTime.ofInstant(instant,CHINA);
    }

    public static Instant toInstant(LocalDate localDate){
        return toInstant(toLocalDateTime(localDate));
    }
    public static Instant toInstant(LocalDateTime localDateTime){
        return localDateTime.toInstant(CHINA);
    }
    public static Instant toInstant(long time, ChronoUnit unit){
        if (ChronoUnit.MILLIS == unit){
            return Instant.ofEpochMilli(time);
        }else if (ChronoUnit.SECONDS == unit){
            return Instant.ofEpochSecond(time);
        }else {
            throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit);
        }
    }

    public static long toEpochSecond(LocalDate localDate){
        return toEpochSecond(toLocalDateTime(localDate));
    }
    public static long toEpochSecond(LocalDateTime localDateTime){
        return localDateTime.toEpochSecond(CHINA);
    }
    public static long toEpochSecond(Instant instant){
        return instant.getEpochSecond();
    }

    public static long toEpochMilli(LocalDate localDate){
        return toEpochMilli(toInstant(localDate));
    }
    public static long toEpochMilli(LocalDateTime localDateTime){
        return toEpochMilli(toInstant(localDateTime));
    }
    public static long toEpochMilli(Instant instant){
        return instant.toEpochMilli();
    }

    public static String format(LocalDate date, String datePattern){
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(datePattern);
        return format(date,formatter);
    }
    public static String format(LocalDate date, DateTimeFormatter formatter){
        return date.format(formatter);
    }

    public static String format(LocalDateTime dateTime, String dateTimePattern){
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(dateTimePattern);
        return format(dateTime,formatter);
    }
    public static String format(LocalDateTime dateTime, DateTimeFormatter formatter){
        return dateTime.format(formatter);
    }

    public static String format(Instant instant, String dateTimePattern){
        return format(toLocalDateTime(instant),dateTimePattern);
    }
    public static String format(Instant instant, DateTimeFormatter formatter){
        return format(toLocalDateTime(instant),formatter);
    }

    public static LocalDate toLocalDate(String date, String datePattern){
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(datePattern);
        return toLocalDate(date,formatter);
    }
    public static LocalDate toLocalDate(String date, DateTimeFormatter formatter){
        return LocalDate.parse(date,formatter);
    }

    public static LocalDateTime toLocalDateTime(String dateTime, String dateTimePattern){
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(dateTimePattern);
        return toLocalDateTime(dateTime,formatter);
    }
    public static LocalDateTime toLocalDateTime(String dateTime, DateTimeFormatter formatter){
        return LocalDateTime.parse(dateTime,formatter);
    }
}
